package com.CST.service.impl.ys;

import cn.hutool.core.date.DateTime;
import com.CST.common.StaticVariable;
import com.CST.common.constant.Constants;
import com.CST.dto.ys.NumAndYardDTO;
import com.CST.dto.ys.YsBusinessBudgetDTO;
import com.CST.entity.cb.BdSysUser;
import com.CST.entity.ys.YsAppealRecord;
import com.CST.entity.ys.YsAssetModifyRecords;
import com.CST.entity.ys.YsComplaint;
import com.CST.entity.ys.YsEtlAssetDetails;
import com.CST.mapper.cst.cb.BdSysUserMapper;
import com.CST.mapper.cst.ys.*;
import com.CST.service.ys.YsComplaintService;
import com.CST.service.ys.YsManageAssetService;
import com.CST.util.ExcelTransfer;
import com.CST.util.HttpUtil;
import com.CST.util.PageHelperTool;
import com.CST.vo.ys.*;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author cw
 */
@Service
public class YsManageAssetServiceImpl extends ServiceImpl<YsManageAssetMapper,YsEtlAssetDetails> implements YsManageAssetService {
    private final ExcelTransfer<YsEtlAssetDetailsVO> excelTransfer;

    @Autowired
    private YsAccountDetailMapper ysAccountDetailMapper;

    @Autowired
    private YsComplaintService complaintService;

    @Autowired
    private BdSysUserMapper userMapper;

    @Autowired
    private YsAppealRecordMapper ysAppealRecordMapper;

    @Autowired
    private YsAssetDetailMapper assetDao;

    public YsManageAssetServiceImpl(ExcelTransfer<YsEtlAssetDetailsVO> excelTransfer) {
        this.excelTransfer = excelTransfer;
    }

    @Override
    public YsManageAssetVO getAssetInfoList(YsBusinessBudgetDTO dto) {
        YsManageAssetVO ysManageAssetVO = new YsManageAssetVO();
        List<YsEtlAssetDetailsVO> resultList = baseMapper.selectYsAssetInfoList(dto);
        resultList = resultList.stream().filter(s -> s.getSubjectCode() !=null).collect(Collectors.toList());
        ysManageAssetVO.setDetailList(PageHelperTool.excutePageInfo(resultList, dto.getPageNum(), dto.getPageSize()));
        List<ExpenseVO> expenseVOList = baseMapper.selectYsAssetListCount(dto);
        BigDecimal total = expenseVOList.stream().
                map(ExpenseVO::getAMOUNT).reduce(BigDecimal.ZERO,BigDecimal::add);
        ExpenseVO evo = new ExpenseVO();
        evo.setSubjectName("总费用");
        evo.setSort(0);
        evo.setAMOUNT(total);
        expenseVOList.add(evo);
        ysManageAssetVO.setExpenseVOList(expenseVOList);
        return ysManageAssetVO;
    }

    @Override
    public int insertManageAsset(YsEtlAssetDetails ysEtlAssetDetails) {
        // 新增项目的num默认为id
        // 查询是否存在相同编号的---固定资产编码
        int count = baseMapper.selectByIdAndYard(ysEtlAssetDetails);
        if (count > 0){
            throw new RuntimeException("编号重复，请重新填写 ");
        }
        ysEtlAssetDetails.setInsertFlag(1);
        ysEtlAssetDetails.setDeleteFlag(0);
        ysEtlAssetDetails.setCreateTime(DateTime.now());
        ysEtlAssetDetails.setCreateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        return baseMapper.insert(ysEtlAssetDetails);
    }

    @Override
    public YsEtlAssetDetails selectInfoByNum(Integer id) {
        return baseMapper.selectById(id);
    }

    @Override
    public int updateManageAssetByNum(YsEtlAssetDetails ysEtlAssetDetails) {
        // 首先去修订记录表中根据用友编号查询，是否存在这条数据的编辑记录
        int count = baseMapper.selectRecordIsExist(ysEtlAssetDetails);
        switch (count){
            case 0:
                // 查询数据，插入修订记录表YS_ASSET_MODIFY_RECORDS
                YsEtlAssetDetails info = baseMapper.selectById(ysEtlAssetDetails.getId());
                YsAssetModifyRecords record = recordSetting("编辑",0);
                baseMapper.insertRecord(info,record);
                // 先删除后插入
                baseMapper.deleteById(ysEtlAssetDetails.getId());
                break;
            case 1:
                baseMapper.deleteById(ysEtlAssetDetails.getId());
                break;
            default:
                break;
        }
        ysEtlAssetDetails.setNum(ysEtlAssetDetails.getId());
        // 更改申诉状态-- 根据编号查询到相应到申诉数据，修改申诉状态
        BdSysUser user = userMapper.getUserById(HttpUtil.getRequestHeaderInfo(Constants.USER_ID));
//        BdSysUser user = userMapper.getUserById("283E3761-5300-43B0-9629-3C175E29D813");
        Optional.ofNullable(user).orElseThrow(()-> new RuntimeException("用户未登录"));
        YsAppealRecord record = new YsAppealRecord();
        record.setNum(ysEtlAssetDetails.getNum());
        record.setStatus(2);
        record.setHandleTime(LocalDateTime.now());
        record.setHandler(user.getId());
        record.setYard(ysEtlAssetDetails.getYard());
        ysAppealRecordMapper.updateByNum(record);

        // 来源 1业务职能，2管理职能-费用类，3管理职能资本类。4管理职能业务配套指标
        AssetDetailVO asset = assetDao.getAssetByNum(record.getNum(), record.getYard());
        if (asset != null){
            complaintService.saveEntity(YsComplaint.builder()
                    .recipient(StaticVariable.LOG_YS_COMPLAINT_RECIPIENT_2)
                    .source(StaticVariable.LOG_YS_COMPLAINT_SOURCE_2)
                    .operate(StaticVariable.LOG_YS_COMPLAINT_OPERATE_3)
                    .acceptContent(StaticVariable.LOG_YS_COMPLAINT_CONTEXT_HEAD_2
                            + asset.getSubjectName() +"("
                            + asset.getSubjectCode() + ")"
                            + StaticVariable.LOG_YS_COMPLAINT_CONTEXT_2)
                    .jumpPage(StaticVariable.LOG_YS_COMPLAINT_PAGE_2)
                    .complaintUser(user.getUserName())
                    .build());
        }
        ysEtlAssetDetails.setDeleteFlag(0);
        ysEtlAssetDetails.setInsertFlag(2);
        ysEtlAssetDetails.setCreateTime(DateTime.now());
        ysEtlAssetDetails.setCreateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        return baseMapper.insert(ysEtlAssetDetails);
    }

    private YsAssetModifyRecords recordSetting(String content, Integer flag) {
        YsAssetModifyRecords record = new YsAssetModifyRecords();
        record.setOperContent(content);
        record.setOperBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        record.setOperTime(LocalDateTime.now());
        record.setRevokeFlag(flag);
        return record;
    }

    @Override
    public Boolean deleteByNum(Long id) {
        // 查询数据，插入修订记录表YS_ASSET_MODIFY_RECORDS
        YsEtlAssetDetails info = baseMapper.selectById(id);
        if (info== null){
            return true;
        }
        YsAssetModifyRecords record = recordSetting("删除",1);
        baseMapper.insertRecord(info,record);
        baseMapper.deleteById(id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean releaseData(YsBusinessBudgetDTO ysBusinessBudgetDto) {
        try {
            List<YsEtlAssetDetailsVO> resultList = baseMapper.selectYsAssetInfoList(ysBusinessBudgetDto);
            // 分批插入YS_ASSETS_DETAIL_RE
            // 先根据条件删除数据
            baseMapper.deleteByDto();
            int total = resultList.size();
            if (total > 0) {
                int fromIndex = 0;
                List<YsEtlAssetDetailsVO> insertList = new ArrayList<>();
                for (YsEtlAssetDetailsVO item : resultList) {
                    fromIndex++;
                    insertList.add(item);
                    if (fromIndex % 50 == 0 && fromIndex <= total) {
                        baseMapper.insertReleaseData(insertList);
                        insertList = new ArrayList<>();
                    }
                }
                if (CollectionUtils.isNotEmpty(insertList)) {
                    baseMapper.insertReleaseData(insertList);
                }
            }
        } catch (RuntimeException e){
            throw new RuntimeException("发布失败");
        }
        return true;
    }

    @Override
    public PageInfo<YsAssetModifyRecords> getModifyRecordList(YsBusinessBudgetDTO dto) {
        List<YsAssetModifyRecords> recordList = baseMapper.selectRecordByDto(dto);
        return PageHelperTool.excutePageInfo(recordList, dto.getPageNum(), dto.getPageSize());
    }

    @Override
    public Boolean revokeRecord(NumAndYardDTO dto) {
        // 根据id查询数据是否存在
        int count = baseMapper.selectRecordById(dto);
        if (count > 0){
            throw new RuntimeException("列表存在重复数据，请删除相同数据再执行撤销操作");
        }
        // 根据id查询数据，根据num将detail表中的数据还原
        baseMapper.updateDetailDeleteFlagById(dto);
        // 逻辑删除修订记录表数据
        baseMapper.DeleteRecordById(dto.getId());
        return true;
    }

    @Override
    public void exportExcelYsManageAsset(HttpServletResponse response, YsBusinessBudgetDTO dto) {
        List<YsEtlAssetDetailsVO> ysEtlAssetDetailsVOS = baseMapper.selectYsAssetInfoList(dto);
        ysEtlAssetDetailsVOS.forEach(t ->{
            if (t.getNum() == null){
                t.setNum(t.getId());
            }
        });
        excelTransfer.exportExcel(response, ysEtlAssetDetailsVOS, "管理资产类预算执行管理", "sheet",
                YsEtlAssetDetailsVO.class);
            }
}
